import type { AssetManager, Node } from "cc";
import { assetManager, Canvas, Component, director, game, resources, Sprite, UITransform, v2, v3, v4, Vec2, Vec3, Vec4, view, warn } from "cc";

const __Global__ = window ?? globalThis;
if(!Reflect.has(__Global__, 'abd')) Reflect.set(__Global__, 'abd', {__abandon__: '$planet_abandon_poof$'});

['$planet_sp_poof$', '$planet_size_poof$', '$planet_vector_poof$', '$planet_cc_poof$']
.forEach(space_name=>{
	if(!Reflect.has(abd, space_name)) Reflect.set(abd, space_name, {[`${space_name}_space`]: space_name});
});

Reflect.defineProperty(abd.$planet_cc_poof$, '$planet_initTime_poof$', {
	get() {
		return Reflect.get(game, '_initTime');
	},
	enumerable: true,
	configurable: false,
});

Reflect.defineProperty(abd.$planet_cc_poof$, '$planet_totalTime_poof$', {
	get() {
		return game.totalTime;
	},
	enumerable: true,
	configurable: false,
});

Reflect.defineProperty(abd.$planet_cc_poof$, '$planet_frameStartTime_poof$', {
	get() {
		return game.frameStartTime - abd.$planet_cc_poof$.$planet_initTime_poof$;
	},
	enumerable: true,
	configurable: false,
});

Reflect.defineProperty(abd.$planet_cc_poof$, '$planet_residueTime_poof$', {
	get() {
		return abd.$planet_cc_poof$.$planet_frameStartTime_poof$+abd.$planet_cc_poof$.$planet_frameTime_poof$-abd.$planet_cc_poof$.$planet_totalTime_poof$;
	},
	enumerable: true,
	configurable: false,
});

Reflect.defineProperty(abd.$planet_cc_poof$, '$planet_frameTime_poof$', {
	get() {
		return game.frameTime;
	},
	enumerable: true,
	configurable: false,
});

Reflect.defineProperty(abd.$planet_cc_poof$, '$planet_is_long_screen_poof$', {
	get(){
		let [R, r] = [abd.$planet_size_poof$.$planet_canvasSize_poof$, abd.$planet_size_poof$.$planet_designSize_poof$].map(s=>s.width/s.height);
		return r > R;
	},
	enumerable: true,
	configurable: false,
});

if(typeof requestIdleCallback !== 'undefined'){
	abd.$planet_cc_poof$.$planet_IdleCallback_poof$ = function(call, args, complete, options){
		if(options){
			if(!Reflect.has(options, 'start_stamp')) options.start_stamp = performance.now();
			if(!Reflect.has(options, 'timeout')) options.timeout = 100;
		}else options = {start_stamp: performance.now(), timeout: 100};

		requestIdleCallback(()=>{
			if(abd.$planet_cc_poof$.$planet_residueTime_poof$>0 || performance.now()-options.start_stamp >= options.timeout){
				Promise.resolve(call(...args)).then(r=> typeof complete == 'function' ? complete(r, args) : void 0);
			}else abd.$planet_cc_poof$.$planet_IdleCallback_poof$(call, args, complete, options);
		});
	}
}else if(typeof requestAnimationFrame !== 'undefined'){
	abd.$planet_cc_poof$.$planet_IdleCallback_poof$ = function(call, args, complete, options){
		if(options){
			if(!Reflect.has(options, 'start_stamp')) options.start_stamp = performance.now();
			if(!Reflect.has(options, 'timeout')) options.timeout = 100;
		}else options = {start_stamp: performance.now(), timeout: 100};
		requestAnimationFrame(()=>{
			if(abd.$planet_cc_poof$.$planet_residueTime_poof$>0 || performance.now()-options.start_stamp >= options.timeout){
				Promise.resolve(call(...args)).then(r=> typeof complete == 'function' ? complete(r, args) : void 0);
			}else abd.$planet_cc_poof$.$planet_IdleCallback_poof$(call, args, complete, options);
		});
	}
}else{
	abd.$planet_cc_poof$.$planet_IdleCallback_poof$ = function(call, args, complete, options){
		if(options){
			if(!Reflect.has(options, 'start_stamp')) options.start_stamp = performance.now();
			if(!Reflect.has(options, 'timeout')) options.timeout = 100;
		}else options = {start_stamp: performance.now(), timeout: 100};
		setTimeout(()=>{
			if(abd.$planet_cc_poof$.$planet_residueTime_poof$>0 || performance.now()-options.start_stamp >= options.timeout){
				Promise.resolve(call(...args)).then(r=> typeof complete == 'function' ? complete(r, args) : void 0);
			}else abd.$planet_cc_poof$.$planet_IdleCallback_poof$(call, args, complete, options);
		}, 0);
	}
}

abd.$planet_cc_poof$.$planet_frameWhile_poof$ = function(list, call){
	if(!list || !Array.isArray(list) || list.length<=0) return Promise.resolve(0);
	let np = new abd.$planet_NudityPromise_poof$<0>();
	list.forEach((el, i)=> abd.$planet_cc_poof$.$planet_IdleCallback_poof$(call, [el, i, list], ()=>(i==list.length-1) ? np.$planet_resolve_poof$(0) : void 0) );
	return np.$planet_promise_poof$;
}

abd.$planet_cc_poof$.$planet_loadBundle_poof$ = function(bundle_name){
	return new Promise<AssetManager.Bundle>((s, j)=>{
		assetManager.loadBundle(bundle_name, null, (err, bundle)=>{
			if(err) s(undefined);
			else if(bundle) s(bundle);
			else s(undefined);
		});
	});
};

abd.$planet_cc_poof$.$planet_loadRes_poof$ = function(path, type, bundle, call){
	//@ts-ignore
	[bundle, call] = abd.$planet_pickValueByType_poof$([bundle, call], [['object', resources], ['function', undefined]]);

	let asset = bundle.get(path, type);
	if(!asset){
		bundle.load(path, type, (err, a)=>{
			if(a) call && call(a);
			else warn('资源加载失败：', path, type, err);
		});
	}else if(call) call(asset);
}

abd.$planet_cc_poof$.$planet_loadResAsync_poof$ = function(path, type, bundle){
	bundle = bundle??resources;

	return new Promise((s, j)=>{
		let asset = bundle.get(path, type);
		if(asset) s(asset);
		else{
			bundle.load(path, type, (err, a)=>{
				if(a) s(a);
				else warn('资源加载失败：', path, type, err);
			});

		}
	});
}

abd.$planet_cc_poof$.$planet_creatEventHandle_poof$ = function(options){
	return Object.assign(new Component.EventHandler(), options);
}

abd.$planet_cc_poof$.$planet_VecAssist_poof$ = class{
	private $planet_inner_poof$: UITransform;
	private $planet_container_poof$: UITransform;
	private $planet___vec___poof$: Vec3;

	constructor(node: Node, ref: Node){
		if (!node.parent){
			abd.$planet_log_poof$.$planet_tag_poof$(`node<${node.name}> 不在场景中，无法使用坐标辅助类的功能!: red`);
			return void 0;
		}

		ref = ref&&ref.isValid ? ref : node.parent;

		[this.$planet_inner_poof$, this.$planet_container_poof$] = [node, ref].map(n=>n.getComponent(UITransform));
		this.$planet___vec___poof$ = v3();
	}

	private get $planet_container_upper_poof$(){
		return this.$planet_container_poof$.height * (1 - this.$planet_container_poof$.anchorY);
	}

	private get $planet_container_bottom_poof$(){
		return this.$planet_container_poof$.height * this.$planet_container_poof$.anchorY;
	}

	private get $planet_container_left_poof$(){
		return this.$planet_container_poof$.width * this.$planet_container_poof$.anchorX;
	}

	private get $planet_container_right_poof$(){
		return this.$planet_container_poof$.width * (1 - this.$planet_container_poof$.anchorX);
	}

	private get $planet_inner_upper_poof$(){
		return this.$planet_inner_poof$.height * (1 - this.$planet_inner_poof$.anchorY);
	}

	private get $planet_inner_bottom_poof$(){
		return this.$planet_inner_poof$.height * this.$planet_inner_poof$.anchorY;
	}

	private get $planet_inner_left_poof$(){
		return this.$planet_inner_poof$.width * this.$planet_inner_poof$.anchorX;
	}

	private get $planet_inner_right_poof$(){
		return this.$planet_inner_poof$.width * (1 - this.$planet_inner_poof$.anchorX);
	}

	public get $planet_top_poof$(){
		return this.$planet_container_upper_poof$ - this.$planet_inner_upper_poof$;
	}

	public get $planet_bottom_poof$(){
		return this.$planet_inner_bottom_poof$ - this.$planet_container_bottom_poof$;
	}

	public get $planet_left_poof$(){
		return this.$planet_inner_left_poof$ - this.$planet_container_left_poof$;
	}

	public get $planet_right_poof$(){
		return this.$planet_container_right_poof$ - this.$planet_inner_right_poof$;
	}

	public get $planet_over_top_poof$(){
		return this.$planet_container_upper_poof$ + this.$planet_inner_bottom_poof$;
	}

	public get $planet_over_bottom_poof$(){
		return -this.$planet_container_bottom_poof$ - this.$planet_inner_upper_poof$;
	}

	public get $planet_over_left_poof$(){
		return -this.$planet_container_left_poof$ - this.$planet_inner_right_poof$;
	}

	public get $planet_over_right_poof$(){
		return this.$planet_container_right_poof$ + this.$planet_inner_left_poof$;
	}

	public get $planet_center_poof$(){
		let x = (0.5 - this.$planet_container_poof$.anchorX) * this.$planet_container_poof$.width + (this.$planet_inner_poof$.anchorX - 0.5) * this.$planet_inner_poof$.width;
		let y = (0.5 - this.$planet_container_poof$.anchorY) * this.$planet_container_poof$.height + (this.$planet_inner_poof$.anchorY - 0.5) * this.$planet_inner_poof$.height;

		return v3(x, y, this.$planet_inner_poof$.node.position.z);
	}

	public get $planet_vec_poof$(){
		return this.$planet___vec___poof$;
	}

	public $planet_getPosition_poof$(x: '$planet_center_poof$'|`$planet_${''|'over_'}${'left'|'right'|'bottom'|'top'}_poof$`, y?:'$planet_center_poof$'|`$planet_${''|'over_'}${'top'|'bottom'}_poof$`){
		if(x.includes('top') || x.includes('bottom')){
			let _t = y;
			y = <typeof y>x;
			x = _t;
			_t = undefined;
		}

		this.$planet_vec_poof$.set(
			x ? x=='$planet_center_poof$' ? this.$planet_center_poof$.x : Reflect.get(this, x) : this.$planet_inner_poof$.node.position.x,
			y ? y=='$planet_center_poof$' ? this.$planet_center_poof$.y : Reflect.get(this, y) : this.$planet_inner_poof$.node.position.y,
			this.$planet_inner_poof$.node.position.z
		);

		return this.$planet_vec_poof$;
	}

	public static $planet_getPosition_poof$<Dx extends '$planet_center_poof$'|`$planet_${''|'over_'}${'left'|'right'|'bottom'|'top'}_poof$`, Dy extends '$planet_center_poof$'|`$planet_${''|'over_'}${'top'|'bottom'}_poof$`>(node: Node, ref?: Node|Dx, x?: Dx|Dy, y?: Dy){
		if(typeof ref == 'string'){
			[x, y as typeof x] = [ref, x];
			ref = undefined;
		}
		let va = new abd.$planet_cc_poof$.$planet_VecAssist_poof$(node, ref as Node);
		let vec = va.$planet_getPosition_poof$(x??'$planet_center_poof$', y);
		va = null;
		return vec;
	}
}

abd.$planet_cc_poof$.$planet_skinPeeler_poof$ = function(node, sframe, inner){
	let uitrans = node.getComponent(UITransform);
	let node_size = uitrans.contentSize.clone();
	let sfrm_size = sframe.originalSize.clone();

	let sprite = node.getComponent(Sprite);
	if(!sprite) sprite = node.addComponent(Sprite);
	sprite.spriteFrame = sframe;

	let ratio: number;
	inner = inner ?? true;
	if(typeof inner=='boolean' || inner.width===inner.height){
		if(typeof inner!='boolean') inner = inner.width;
		ratio = Math[inner ? 'min' : 'max'](node_size.width / sfrm_size.width, node_size.height / sfrm_size.height);
	}else{
		let side = inner.width ? 'width' : 'height';
		ratio = node_size[side] / sfrm_size[side];
	}

	uitrans.setContentSize(sfrm_size.width * ratio, sfrm_size.height * ratio);
}

abd.$planet_cc_poof$.$planet_getWorldPosition_poof$ = function(node, out){
	if(!node || !node.isValid) return void 0;

	return node.getWorldPosition(out??v3());
}

abd.$planet_cc_poof$.$planet_getLocalPosition_poof$ = function(local: Node, node: Vec3|Node, out?: Vec3){
	if([local && local.isValid, node instanceof Vec3 ? true : (node && node.isValid)].includes(false)) return void 0;

	return local.getComponent(UITransform).convertToNodeSpaceAR(node instanceof Vec3 ? node : abd.$planet_cc_poof$.$planet_getWorldPosition_poof$(node), out??v3());
};

abd.$planet_cc_poof$.$planet_v2_poof$ = function(__x__, y){
	if(__x__ instanceof Vec2) return __x__;

	let x: number;
	if(typeof __x__ == 'number'){
		x = __x__;
		y = y??x;
	}else ({x, y} = __x__);

	return v2(x, y);
}

abd.$planet_cc_poof$.$planet_v3_poof$ = function(__x__, y, z){
	if(__x__ instanceof Vec3) return __x__;

	let x: number;
	if(typeof __x__ == 'number'){
		x = __x__;
		y = y??x;
		z = z??y;
	}else if(__x__ instanceof Vec2){
		z = y??0;
		({x, y} = __x__);
	}else if(__x__ instanceof Vec4){
		({x, y, z} = __x__);
	}

	return v3(x, y, z);
}

abd.$planet_cc_poof$.$planet_v4_poof$ = function(__x__, y, z, w){
	if(__x__ instanceof Vec4) return __x__;

	let x: number;
	if(typeof __x__  == 'number'){
		x = __x__;
		y = y??x;
		z = z??y;
		w = w??z;
	}else if(__x__ instanceof Vec2){
		w = z??0;
		z = y??0;
		({x, y} = __x__);
	}else if(__x__ instanceof Vec3){
		w = z??0;
		({x, y, z} = __x__);
	}

	return v4(x, y, z, w);
}

Reflect.defineProperty(abd.$planet_cc_poof$, '$planet_canvas_poof$', {
	get(){
		return director.getScene().getComponentInChildren(Canvas);
	},
	enumerable: true,
	configurable: false,
});

Reflect.defineProperty(abd.$planet_size_poof$, '$planet_designSize_poof$', {
	get() {
		return view.getDesignResolutionSize();
	},
	enumerable: true,
	configurable: false,
});

Reflect.defineProperty(abd.$planet_size_poof$, '$planet_canvasSize_poof$', {
	get() {
		return abd.$planet_cc_poof$.$planet_canvas_poof$.getComponent(UITransform).contentSize;
	},
	enumerable: true,
	configurable: false,
});

abd.$planet_size_poof$.$planet_innerRatio_poof$ = function(target, container){
	let [R, r] = [container, target].map(s=>s.width / s.height);
	/** @type {number} */
	let ratio: number;
	if(r > R) ratio = container.width / target.width;
	else ratio = container.height / target.height;
	return ratio;
}

abd.$planet_size_poof$.$planet_exterRatio_poof$ = function(target, filler){
	let [R, r] = [target, filler].map(s=>s.width / s.height);
	/** @type {number} */
	let ratio: number;
	if(R > r) ratio = filler.height / target.height;
	else ratio = filler.width / target.width;
	return ratio;
}

abd.$planet_vector_poof$.$planet_distance_poof$ = function(a, b){

	if([a, b].map(v=>v instanceof Vec2).includes(true)) return Vec2.subtract(v2(), abd.$planet_cc_poof$.$planet_v2_poof$(a), abd.$planet_cc_poof$.$planet_v2_poof$(b)).length();

	if([a, b].map(v=>v instanceof Vec3).includes(true)) return Vec3.subtract(v3(), abd.$planet_cc_poof$.$planet_v3_poof$(a), abd.$planet_cc_poof$.$planet_v3_poof$(b)).length();

	return Vec4.subtract(v4(), abd.$planet_cc_poof$.$planet_v4_poof$(a), abd.$planet_cc_poof$.$planet_v4_poof$(b)).length();
}